import logging
import json
import os
import requests

import numpy as np
import pandas as pd

from .opt_utils import np_converter
from .constants import OPT_PATH


class TWOGISDistanceMatrixAPI:
    def __init__(self, config_path='config/2GIS_DM_params.json', opt_back_path=OPT_PATH):
        self.logger = logging.getLogger('DistanceMatrixAPI')
        self.logger.debug(f"Initializing DistanceMatrixAPI")
        try:
            with open(os.path.join(opt_back_path, config_path), 'r') as f:
                self.api_params = json.load(f)
                self.key = self.api_params['key']
                self.api_params.pop('key', None)
                self.city = self.api_params['city']
                self.api_params.pop('city', None)
        except Exception as e:
            self.logger.error(f"Couldn't load config {config_path}, {e}")
            raise FileNotFoundError("Couldn't load config")

    def get_pair_distance(self, origin, destination, request_params):
        source_lat, source_lon = origin
        self.api_params['source'] = {
            'point': {
                'lat': source_lat,
                'lon': source_lon
            }
        }
        target_lat, target_lon = destination
        self.api_params['target'] = {
            'point': {
                'lat': target_lat,
                'lon': target_lon
            }
        }

        try:
            response = requests.post(f"http://catalog.api.2gis.ru/ctx/2.0/{self.city}/?key={self.key}",
                                     data=json.dumps(self.api_params, default=np_converter))
            shortest_duration = response.json()[0]['total_duration']
            distance = 100000
        except json.JSONDecodeError:
            self.logger.warning('Got empty json from 2GIS')
            distance = np.nan
            shortest_duration = np.nan
        except IndexError:
            self.logger.warning('Got no routes from 2GIS')
            distance = np.nan
            shortest_duration = np.nan
        except Exception as e:
            self.logger.warning(f'Got unknown error from 2GIS: {e}')
            distance = np.nan
            shortest_duration = np.nan
        return (origin, origin, destination, destination,
                distance, shortest_duration, request_params['date'].strftime('%Y-%m-%d'), '2GIS')

    def get_distance(self, origin, destinations, request_params):
        request_result = []
        self.logger.debug(f"Connecting to 2GIS API")

        for destination in destinations:
            result_row = self.get_pair_distance(origin, destination, request_params)
            request_result.append(result_row)

        request_result = pd.DataFrame(request_result,
                                      columns=['origin', 'origin_norm', 'destination', 'destination_norm',
                                               'distance', 'duration', 'date', 'source'])
        return request_result
